/*
 * Copyright 2014 alexpad@gmail.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package alexpad.karaokarc.gui.songList;

import alexpad.karaokarc.*;
import alexpad.karaokarc.midi.*;
import java.awt.*;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;

/**
 *
 * @author alexpad@gmail.com
 */
public class SongListPanel extends javax.swing.JPanel {
	
	private Object columns[];
	private int align[];
	private Object rows[][];
	
	private TableRowSorter rowSorter;
	
	public void updateRowFilter(SearchRowFilter filter){
		rowSorter.setRowFilter(filter);
	}
	
	public SongListPanel() {
		initComponents();
		searchPanel.setSongListPanel(this);
		columns = new Object[]
			{"Artista"	, "Titolo"		, "Tipo"		, "Voto"		, "Dim"			, "Stato"		, "Durata"		, "BPM"			, "File"		, "Azioni"		};
		align = new int[]
			{JLabel.LEFT, JLabel.LEFT	, JLabel.CENTER	, JLabel.CENTER	, JLabel.RIGHT	, JLabel.CENTER	, JLabel.RIGHT	, JLabel.CENTER	, JLabel.LEFT	, JLabel.CENTER	};
		rows = new Object[0][columns.length];
		table.setModel(new DefaultTableModel(rows, columns));
	}

	public void setup(MidiArchive midiArchive) {
		if(midiArchive==null) return;
		
		List<MidiSongInfo> infos = midiArchive.getInfosAsList();
		rows = new Object[infos.size()][columns.length];
		MidiSongInfo info;
		int c;
		for(int n=0;n<infos.size();n++){
			info = infos.get(n);
			c=0;
			rows[n][c++] = info.getArtist();
			rows[n][c++] = info.getTitle();
			rows[n][c++] = info.getType().name();
			rows[n][c++] = info.getScore();
			rows[n][c++] = info.getFileSizeAsString();
			switch(info.getStatus()){
				case MIDI_INVALID:
					rows[n][c++] = "Non valido";
				break;
				case MIDI_VALID:
					rows[n][c++] = "OK";
				break;
				default:
					c++;
			}
			rows[n][c++] = info.getDuration();
			rows[n][c++] = info.getBpm();
			rows[n][c++] = info.getFileName();
		}
		
		table.setModel(new DefaultTableModel(rows, columns) {

			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
			
		});
		
		rowSorter = new TableRowSorter<>(table.getModel());
		table.setRowSorter(rowSorter);
		
		for(int n=0;n<columns.length;n++){
			align(n, align[n]);
		}
		
		autofitAllColumns();
	}
	

	/**
	 * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tableScrollPanel = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();
        searchPanel = new alexpad.karaokarc.gui.songList.SearchPanel();

        setLayout(new java.awt.BorderLayout());

        table.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        tableScrollPanel.setViewportView(table);

        add(tableScrollPanel, java.awt.BorderLayout.CENTER);
        add(searchPanel, java.awt.BorderLayout.PAGE_START);
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private alexpad.karaokarc.gui.songList.SearchPanel searchPanel;
    private javax.swing.JTable table;
    private javax.swing.JScrollPane tableScrollPanel;
    // End of variables declaration//GEN-END:variables
	
	
	private void alignRight(int columnIndex) {
		align(columnIndex, JLabel.RIGHT);
	}
	
	private void alignCenter(int columnIndex) {
		align(columnIndex, JLabel.CENTER);
	}
	
	private void align(int columnIndex, int align) {
		TableColumn column = table.getColumnModel().getColumn(columnIndex);
		DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer();
		cellRenderer.setHorizontalAlignment(align);
		column.setCellRenderer(cellRenderer);
	}
	
	public void autofitAllColumns() {
		TableColumnModel model = table.getColumnModel();
		for(int n=0;n<model.getColumnCount();n++) {
			autofitColumn(n);
		}
	}
	
	private void autofitColumn(int columnIndex) {
		TableColumn column = table.getColumnModel().getColumn(columnIndex);

		int columnHeaderWidth = getColumnHeaderWidth(column);
		int columnDataWidth   = getColumnDataWidth(column);
		int width    = Math.max(columnHeaderWidth, columnDataWidth);

		updateTableColumn(column, width);
	}
	
	private int getColumnHeaderWidth(TableColumn column) {
		Object value = column.getHeaderValue();
		TableCellRenderer renderer = column.getHeaderRenderer();
		if (renderer==null){
			renderer = table.getTableHeader().getDefaultRenderer();
		}
		Component c = renderer.getTableCellRendererComponent(table, value, false, false, -1, column.getModelIndex());
		return c.getPreferredSize().width;
	}
	
	private int getColumnDataWidth(TableColumn column){
		int preferredWidth = 0;
		int maxWidth = column.getMaxWidth();
		for (int row = 0; row < table.getRowCount(); row++) {
    		preferredWidth = Math.max(preferredWidth, getCellDataWidth(row, column));
			//  We've exceeded the maximum width, no need to check other rows
			if (preferredWidth >= maxWidth) break;
		}
		return preferredWidth;
	}
	
	private int getCellDataWidth(int row, TableColumn column){
		TableCellRenderer cellRenderer = table.getCellRenderer(row, column.getModelIndex());
		Component c = table.prepareRenderer(cellRenderer, row, column.getModelIndex());
		int width = c.getPreferredSize().width + table.getIntercellSpacing().width;
		return width;
	}
	
	private void updateTableColumn(TableColumn column, int width) {
		width = Math.max(width, column.getPreferredWidth());
		table.getTableHeader().setResizingColumn(column);
		column.setWidth(width);
	}

}
